home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-04 | 15.7 KB | 589 lines | [TEXT/MPPS] |
- {-----------------------------------------------------------------
-
- This is an AboutBox program for the Devil in a Blue Dress group map
- project for Marathon.
-
- This application demonstrates scrolling movie credits with asynchronous
- sound playing. To build the FAT application, first build the 68K application,
- then build the PPC application and it will automatically be FAT.
-
- The technique for scrolling the text was taken from Metrowerks CodeWarrior
- About application.
-
- Project includes:
-
- DevilAbout.p Source code
- DevilAboutSA.µ 68k project
- SADevilFAT.µ PPC project
- DevilAbout.µ.rsrc Main resources
-
- Date: 11/20/95
- Programmed by Bill Catambay, catambay@aol.com
- -----------------------------------------------------------------}
-
- PROGRAM AboutBox;
-
-
- USES
- QuickDraw, Fonts, Events, Windows, TextEdit, Dialogs, Types, Qdoffscreen, Sound,
- TextEdit, ToolUtils, Resources, Processes;
-
- Const
- FadeLevels = 12;
- aboutSound = 1240;
- endSound = 128;
- kDiscovery = 10001;
- kTreachery = 10008;
- kShowdown = 10014;
- kRetribution = 10018;
- kFinal = 10100;
- TEXTCredits = 128;
-
- Type
- AnimateState = (animateWaiting, animateActive, animateDone);
- CreditsRec = record
- theGWorldP: GWorldPtr;
- viewRect: Rect;
- pictRect: Rect;
- pictHeight: integer;
- end;
-
- Var
- Picts: array[1..5] of integer;
- pictRefnum: integer;
- pictNum: integer;
- noPicts: boolean;
- sndRefnum: integer;
- PixelDepth: integer;
- speed: integer;
- centerFrame: Rect;
- aboutBoxWindow: WindowPtr;
- drawWorld: GWorldPtr;
- backWorld: GWorldPtr;
- curWorld: GworldPtr;
- loopWorld: GworldPtr;
- looprect: rect;
- saveGW: GWorldPtr;
- saveGD: GDHandle;
- err: OSErr;
- event: EventRecord;
- exitSignal: boolean;
- gotEvent: boolean;
- theCreditsRec: CreditsRec;
- theSoundChannelP: SndChannelPtr;
- theSoundH, endsoundH: Handle;
- SndChanStat: SCStatus;
- loopSound: boolean;
- animCreditsFade: AnimateState;
- animCreditsScroll: AnimateState;
- fadeColor: RGBColor;
- grayIndex: integer;
- grayLevels: ARRAY[0..FadeLevels-1] OF integer;
- ticks: longint;
- startTicks: longint;
- endTicks: longint;
- waitTicks: longint;
- i,j: integer;
- fontnum: integer;
- creditsWidth: integer;
- creditsBox: Rect;
- offScreen: boolean;
-
- Procedure DisplayWarning(strID: integer);
-
- Var
- Warningstr: stringHandle;
- dummy: integer;
-
- begin
- WarningStr := GetString(strID);
- if WarningStr = NIL then
- ParamText('Unknown error occurred','','','')
- else
- ParamText(WarningStr^^,'','','');
- dummy := Alert(128,NIL);
- end; { of displayWarning }
-
- Function CenterRect(crect: rect;
- mainrect: rect): rect;
-
- Var
- prect: rect;
-
- begin
- prect.top := (mainrect.bottom - mainrect.top - (crect.bottom -
- crect.top)) div 2 + mainrect.top;
- prect.bottom := prect.top + (crect.bottom - crect.top);
- prect.left := (mainrect.right - mainrect.left - (crect.right -
- crect.left)) div 2 + mainrect.left;
- prect.right := prect.left + (crect.right - crect.left);
- CenterRect := prect;
- end; { of centerPict }
-
- Procedure GoMainscreen;
-
- begin
- SetGWorld(saveGW,saveGD);
- UnlockPixels(curWorld^.portPixMap);
- offScreen := FALSE;
- end;
-
- Procedure GoOffscreen(var offWorld: GworldPtr);
-
- begin
- GetGworld(saveGW,saveGD);
- if not lockPixels(offWorld^.portPixMap) then;
- SetGWorld(offWorld,NIL);
- curWorld := offWorld;
- offScreen := TRUE;
- end;
-
- Procedure SetCreditView;
-
- Var
- offset: integer;
- textid: integer;
- outGWorldP: GWorldPtr;
- theText: Handle;
- theTE: TEHandle;
- theStyle: StScrpHandle;
-
- begin
- DisposeGWorld(drawWorld);
- case picts[pictNum] of
- kDiscovery,
- kShowdown,
- kRetribution: offset := 0;
- kTreachery: offset := 350;
- kFinal: offset := 100;
- {CASE} end;
- if noPicts then
- offset := 200;
- with theCreditsRec.viewRect do
- begin
- right := aboutBoxWindow^.portRect.right - 20 - offset;
- left := right - 250;
- top := aboutBoxWindow^.portRect.top + 170;
- bottom := top + 160;
- end;
- if NoErr <> NewGWorld(drawWorld, PixelDepth, theCreditsRec.viewRect, NIL, NIL, 0) then
- ExitToShell;
- creditsBox := theCreditsRec.viewRect;
- if theCreditsRec.theGWorldP <> NIL then
- begin
- DisposeGWorld(theCreditsRec.theGWorldP);
- theCreditsRec.theGWorldP := NIL;
- end;
- textid := TEXTCredits + pictNum - 1;
- { Put Text in a TERecord. }
- theTE := TEStyleNew(CreditsBox, CreditsBox);
- theText := GetResource('TEXT', textid);
- theStyle := StScrpHandle(GetResource('styl', textid));
- HLock(theText);
- HidePen;
- TEStyleInsert(theText^, GetHandleSize(theText), theStyle, theTE);
- ShowPen;
- HUnLock(theText);
- ReleaseResource(theText);
- if theStyle <> NIL then
- ReleaseResource(Handle(theStyle));
- TESetAlignment(teJustCenter, theTE);
- TECalText(theTE);
- { Determine height of the Text. }
- CreditsBox.right := CreditsBox.right - CreditsBox.left;
- CreditsBox.left := 0;
- CreditsBox.top := 0;
- CreditsBox.bottom := TEGetHeight(theTE^^.nLines, 0, theTE);
- { Create new GWorld that is the height of the Text. }
- err := NewGWorld(outGWorldP, pixelDepth, CreditsBox, NIL,
- GetGWorldDevice(drawWorld), noNewDevice);
- GoOffscreen(outGWorldP);
- EraseRect(CreditsBox);
- { Draw Text inside GWorld. }
- theTE^^.viewRect := CreditsBox;
- theTE^^.destRect := CreditsBox;
- theTE^^.inPort := GrafPtr(outGWorldP);
- TEUpdate(CreditsBox, theTE);
- TEDispose(theTE);
- InvertRect(CreditsBox); { White letters on black background }
- GoMainScreen;
- theCreditsRec.theGWorldP := outGWorldP;
- theCreditsRec.pictRect.left := 0;
- theCreditsRec.pictRect.top := 0;
- theCreditsRec.pictRect.right := theCreditsRec.viewRect.right - theCreditsRec.viewRect.left;
- theCreditsRec.pictRect.bottom := theCreditsRec.viewRect.bottom - theCreditsRec.viewRect.top;
- theCreditsRec.pictHeight := creditsBox.bottom;
- end;
-
- Procedure UpdateLoopWorld;
-
- begin
- if loopWorld = NIL then
- exit(updateLoopWorld);
- GoOffscreen(loopWorld);
- CopyBits(GrafPtr(aboutBoxWindow)^.portBits, GrafPtr(loopWorld)^.portBits,
- loopRect, loopWorld^.portRect, srcCopy, NIL);
- GoMainscreen;
- if loopSound then
- begin
- setport(aboutBoxWindow);
- textsize(10);
- foreColor(yellowColor);
- moveto(looprect.left, looprect.top - 4 + (looprect.bottom - looprect.top + 1) div 2);
- DrawString('Continuous Play');
- foreColor(blackColor);
- end;
- end; { of updateLoopWorld }
-
- Procedure NewPict;
-
- Var
- thePicture: PicHandle;
- reset: boolean;
-
- begin
- if picts[pictNum] = kTreachery then
- reset := true;
- pictNum := 1 + (pictNum mod 5);
- if picts[pictNum] = kTreachery then
- reset := true;
- SetCreditView;
- UseResFile(pictRefnum);
- if noPicts then
- thePicture := GetPicture(picts[1])
- else
- thePicture := GetPicture(picts[pictNum]);
- UseResFile(curResFile);
- if thePicture = NIL then
- begin
- displayWarning(129);
- noPicts := true;
- UseResFile(pictRefnum);
- thePicture := GetPicture(picts[1]);
- UseResFile(curResFile);
- SetCreditView;
- end;
- if thePicture = NIL then
- ExitToShell;
- GoOffscreen(backWorld);
- drawPicture(thePicture, backWorld^.portRect);
- GoMainscreen;
- ReleaseResource(handle(thePicture));
- CopyBits(GrafPtr(backWorld)^.portBits, GrafPtr(aboutBoxWindow)^.portBits,
- backWorld^.portRect, backWorld^.portRect, srcCopy, NIL);
- updateLoopWorld;
- err := SndPlay(theSoundChannelP, SndListHandle(theSoundH), true);
- end;
-
- Function CheckCurrent: boolean;
-
- Var
- i: integer;
- thePicture: PicHandle;
-
- begin
- checkCurrent := false;
- for i := 2 to 5 do
- begin
- thePicture := GetPicture(picts[i]);
- if thePicture = NIL then
- begin
- checkCurrent := true;
- exit(checkCurrent);
- end;
- ReleaseResource(handle(thePicture));
- end;
- end; { of checkCurrent }
-
- Procedure SetUpGraphics;
-
- Var
- thePicture: PicHandle;
- picFrame: Rect;
-
- begin
- picts[1] := kDiscovery;
- picts[2] := kTreachery;
- picts[3] := kShowdown;
- picts[4] := kRetribution;
- picts[5] := kFinal;
- sndRefnum := OpenResFile('Sounds');
- if sndRefnum = -1 then
- sndRefnum := curResFile;
- pictRefnum := OpenResFile('Shapes');
- if pictRefnum = -1 then
- pictRefnum := OpenResFile('Devil Installer');
- noPicts := pictRefnum = -1;
- if noPicts then
- begin
- pictRefnum := curResFile;
- noPicts := checkCurrent;
- end;
- if noPicts then
- displayWarning(128);
- UseResFile(pictRefnum);
- GetFNum('Monaco', fontnum);
- PixelDepth := 16;
- offScreen := false;
- loopSound := false;
- pictNum := 1;
- thePicture := GetPicture(picts[pictNum]);
- UseResFile(curResFile);
- if thePicture = NIL then
- ExitToShell;
- startTicks := TickCount;
- picFrame := thePicture^^.picFrame;
- centerFrame := centerRect(picFrame,qd.screenBits.bounds);
- aboutBoxWindow := NewCWindow(NIL,centerFrame,'', TRUE, plainDBox,pointer(-1), FALSE, 0);
- if NoErr <> NewGWorld(backWorld, PixelDepth, picFrame, NIL, NIL, 0) then
- ExitToShell;
- GoOffscreen(backWorld);
- drawPicture(thePicture, picFrame);
- GoMainscreen;
- ReleaseResource(handle(thePicture));
- CopyBits(GrafPtr(backWorld)^.portBits, GrafPtr(aboutBoxWindow)^.portBits,
- picFrame, picFrame, srcCopy, NIL);
- startTicks := TickCount - startTicks;
- speed := (startTicks - 23) div 18;
- if speed < 1 then
- speed := 1
- else if speed > 7 then
- speed := 7;
- end;
-
- Function Num2Str (num: integer): string;
-
- Var
- str: str255;
-
- begin
- NumToString(num, str);
- Num2Str := str;
- end; { of Num2Str }
-
- Procedure UpdateStatus;
-
- Var
- ch: char;
-
- begin
- ch := CHR(BAnd(Event.message, charCodeMask));
- case ch of
- chr(30): inc(speed);
- chr(31): dec(speed);
- chr(28): begin
- pictNum := 3 + (pictNum mod 5);
- newPict;
- end;
- chr(29): newPict;
- 'l','L': begin
- if loopWorld = NIL then
- begin
- setRect(loopRect,0,0,90,25);
- if NoErr <> NewGWorld(loopWorld, PixelDepth, looprect, NIL, NIL, 0) then
- ExitToShell;
- offsetRect(loopRect,10,aboutBoxWindow^.portRect.bottom - 22);
- end;
- loopSound := not loopSound;
- if not loopSound then
- CopyBits(GrafPtr(loopWorld)^.portBits, GrafPtr(aboutBoxWindow)^.portBits,
- loopWorld^.portRect, loopRect, srcCopy, NIL)
- else
- UpdateLoopWorld;
- end;
- {CASE} end;
- if speed = 0 then
- speed := 1;
- end; { of updateStatus }
-
- Function CheckSound: boolean;
-
- Var
- sndOn: boolean;
-
- begin
- if theSoundChannelP <> NIL then
- begin
- Err := SndChannelStatus(theSoundChannelP, sizeof(SndChanStat), @SndChanStat);
- if Err = NoErr then
- sndOn := SndChanStat.scChannelBusy
- else
- sndOn := false;
- end;
- checkSound := sndOn;
- end;
-
- BEGIN
- InitGraf(@qd.thePort);
- InitFonts;
- InitWindows;
- InitMenus;
- TEInit;
- InitDialogs(NIL);
- InitCursor;
- MaxApplZone;
- MoreMasters;
- SetUpGraphics;
- theSoundChannelP := NIL;
- theSoundH := NIL;
- endSoundH := NIL;
- grayLevels[0] := 4369;
- grayLevels[1] := 8738;
- grayLevels[2] := 17476;
- grayLevels[3] := 21845;
- grayLevels[4] := 30583;
- grayLevels[5] := -30584;
- grayLevels[6] := -21846;
- grayLevels[7] := -17477;
- grayLevels[8] := -13108;
- grayLevels[9] := -8557;
- grayLevels[10] := -4370;
- grayLevels[11] := -1;
- theCreditsRec.theGWorldP := NIL;
- SetCreditView;
- UseResFile(sndRefNum);
- theSoundH := GetResource('snd ', aboutSound);
- endSoundH := GetResource('snd ', endSound);
- UseResFile(curResFile);
- HLockHi(theSoundH);
- if theSoundH <> NIL then
- begin
- err := SndNewChannel(theSoundChannelP, sampledSynth, initMono, NIL);
- if err = noErr then
- err := SndPlay(theSoundChannelP, SndListHandle(theSoundH), true);
- end;
- FlushEvents(everyEvent,0);
- exitSignal := false;
- animCreditsFade := animateActive;
- animCreditsScroll := animateWaiting;
- grayIndex := 0;
- repeat
- if loopSound & (not CheckSound) then
- err := SndPlay(theSoundChannelP, SndListHandle(theSoundH), true);
- startTicks := TickCount;
- gotEvent := WaitNextEvent(mDownMask + keyDownMask + osMask,event,1,NIL);
- if gotEvent & (event.what = keyDown) then
- updateStatus;
- if gotEvent & (event.what = mouseDown) then
- exitSignal := true;
- if gotEvent & (event.what = osEvt) then
- if band(brotl(event.message,8),$FF) = suspendResumeMessage then
- if BAnd(event.message,resumeFlag) = 0 then
- exitSignal := true;
- if (animCreditsFade = animateActive) and
- (grayIndex >= FadeLevels) then
- begin
- animCreditsFade := animateDone;
- Delay(30, ticks);
- animCreditsScroll := animateActive;
- end;
- if (animCreditsScroll = animateActive) and
- (theCreditsRec.pictRect.top > theCreditsRec.pictHeight) then
- begin
- theCreditsRec.pictRect.top := 1;
- theCreditsRec.pictRect.bottom := theCreditsRec.viewRect.bottom -
- theCreditsRec.viewRect.top + 1;
- end;
- if animCreditsFade = animateActive then
- begin
- Delay(3, ticks);
- GoOffScreen(drawWorld);
- CopyBits(GrafPtr(theCreditsRec.theGWorldP)^.portBits, GrafPtr(drawWorld)^.portBits,
- theCreditsRec.pictRect, theCreditsRec.viewRect, srcCopy, NIL);
- fadeColor.red := grayLevels[grayIndex];
- fadeColor.blue := grayLevels[grayIndex];
- fadeColor.green := grayLevels[grayIndex];
- grayIndex := grayIndex + 1;
- RGBForeColor(fadeColor);
- PenMode(adMin);
- PaintRect(theCreditsRec.viewRect);
- PenMode(patCopy);
- ForeColor(blackColor);
- CopyBits(GrafPtr(backWorld)^.portBits, GrafPtr(drawWorld)^.portBits,
- theCreditsRec.viewRect, theCreditsRec.viewRect, adMax, NIL);
- GoMainScreen;
- CopyBits(GrafPtr(drawWorld)^.portBits, GrafPtr(aboutBoxWindow)^.portBits,
- theCreditsRec.viewRect, theCreditsRec.viewRect, srcCopy, NIL);
- end;
- if animCreditsScroll = animateActive then
- begin
- creditsWidth := theCreditsRec.viewRect.right -
- theCreditsRec.viewRect.left - 1;
- GoOffScreen(drawWorld);
- theCreditsRec.pictRect.top := theCreditsRec.pictRect.top + speed;
- theCreditsRec.pictRect.bottom := theCreditsRec.pictRect.bottom + speed;
- if theCreditsRec.pictRect.bottom <= theCreditsRec.pictHeight then
- CopyBits(GrafPtr(theCreditsRec.theGWorldP)^.portBits, GrafPtr(drawWorld)^.portBits,
- theCreditsRec.pictRect, theCreditsRec.viewRect, srcCopy, NIL)
- else
- begin
- GoMainScreen;
- animCreditsScroll := animateDone;
- cycle;
- end;
- PenMode(adMin); { Fade out at top and fade in at bottom. }
- j := FadeLevels - 1;
- For i := 0 TO j - 1 do
- begin
- fadeColor.red := grayLevels[i];
- fadeColor.blue := grayLevels[i];
- fadeColor.green := grayLevels[i];
- RGBForeColor(fadeColor);
- MoveTo(theCreditsRec.viewRect.left, theCreditsRec.viewRect.top + i);
- Line(creditsWidth, 0);
- MoveTo(theCreditsRec.viewRect.left, theCreditsRec.viewRect.bottom - i - 1);
- Line(creditsWidth, 0);
- end;
- ForeColor(blackColor);
- PenMode(patCopy);
- CopyBits(GrafPtr(backWorld)^.portBits, GrafPtr(drawWorld)^.portBits,
- theCreditsRec.viewRect, theCreditsRec.viewRect, adMax, NIL);
- GoMainScreen;
- CopyBits(GrafPtr(drawWorld)^.portBits, GrafPtr(aboutBoxWindow)^.portBits,
- theCreditsRec.viewRect, theCreditsRec.viewRect, srcCopy, NIL);
- end;
- if animCreditsScroll = animateDone then
- begin
- if pictNum = 5 then
- begin
- animCreditsScroll := animateWaiting;
- WaitTicks := TickCount;
- err := SndPlay(theSoundChannelP, SndListHandle(endSoundH), true);
- end
- else
- begin
- animCreditsScroll := animateActive;
- NewPict;
- end;
- end;
- if (animCreditsScroll = animateWaiting) and
- (animCreditsFade = animateDone) then
- if WaitTicks + 180 <= TickCount then
- begin
- animCreditsFade := animateActive;
- grayIndex := 0;
- NewPict;
- end;
- EndTicks := TickCount;
- if endTicks = startTicks then
- while endTicks = TickCount do; { Just in case the CPU is _that_ fast }
- until exitSignal;
- FlushEvents(Bor(mDownMask, Bor(mUpMask, Bor(keyDownMask, Bor(keyUpMask,autoKeyMask)))),0);
- if theCreditsRec.theGWorldP <> NIL then
- DisposeGWorld(theCreditsRec.theGWorldP);
- if loopWorld <> NIL then
- DisposeGWorld(loopWorld);
- HUnlock(theSoundH);
- HUnlock(endSoundH);
- if theSoundChannelP <> NIL then
- err := SndDisposeChannel(theSoundChannelP, true);
- if theSoundH <> NIL then
- ReleaseResource(theSoundH);
- if endSoundH <> NIL then
- ReleaseResource(endSoundH);
- DisposeGWorld(drawWorld);
- DisposeGWorld(backWorld);
- DisposeWindow(WindowPtr(aboutBoxWindow));
- PurgeMem(maxSize);
- END.
-